#include "common.h"

#include <sstream>

logger* logger::instance_ = NULL;

logger::logger()
{
	memset(&hostname_, 0, sizeof(char)*64);
	gethostname(hostname_, 64);
	pthread_mutex_init(&mu_, NULL);
}
logger::~logger()
{
	if(file_.is_open()) {
		file_.close();
	}
	pthread_mutex_destroy(&mu_);
}
logger* logger::get_instance()
{
	if(instance_ == NULL) {
		instance_ = new logger();
	}
	return instance_;
}
int logger::set_log_file(const string file)
{
	file_.open(file.c_str(), ofstream::app | ofstream::out);
	if(!file_.is_open()) {
		return -1;
	}
	return 0;
}
void logger::log(const char * format, ...)
{
	if(!file_.is_open()) {
		return;
	}
	time_t timep;
	struct tm *p;
	va_list argptr;
	char buf[768];

	va_start(argptr, format);
	vsprintf(buf, format, argptr);
	va_end(argptr);
	
	char logstr[1024];
	time(&timep);
	p = localtime(&timep);
	
	sprintf(logstr, "%04d-%02d-%02d %02d:%02d:%02d [%s] %s", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, hostname_, buf);
	file_ << logstr;
	file_.flush();

	return;

}
void logger::direct_log(const char *buf)
{
	if(!file_.is_open()) {
		return;
	}

	file_ << buf;
	file_.flush();

	return;
}
int logger::ex_log_callback(const char* str)
{
	logger::get_instance()->direct_log(str);
	return 0;
}

configure* configure::instance_ = NULL;

configure* configure::get_instance()
{
	if(instance_ == NULL) {
		instance_ = new configure();
	}
	return instance_;
}
int configure::get_config(const string& path)
{
	string buf;
	ifstream file(path.c_str());
	if(!file.is_open() ) {
		LOG("config get %s fail.",path.c_str());
		return -1;
	}
	while(file.good() )
	{
		getline(file, buf, '\n');
    parse_line(buf);
	}
	file.close();
  // read ukey data
  if (this->get_int("ukey") == 1) {
    std::string ukey_data;
    if (read_ukey_data(&ukey_data) == false) {
      LOG("read ukey data fail.");
      return -1;
    }

    std::string line;
    std::stringstream ss(ukey_data);
    while (std::getline(ss, line)) {
      parse_line(line);
    }
  }
	return 0;
}

void configure::parse_line(const std::string& line) {
  if(line.find("#") == 0 || line.find("=") == string::npos) {
    return;
  } else {
    string::size_type n = line.find("=");
    string key = line.substr(0, n);
    string val = line.substr(n+1);
    kv_.insert(make_pair(key, val) );
  }
}

bool configure::read_ukey_data(std::string* data) {
  data->clear();

  FILE *fp;
  int status;

  fp = popen("dra_ukey", "r");
  if (fp == NULL) {
    return false;
  }

  char buf[512];
  size_t n;
  while (true) {
    n = fread(buf, 1, sizeof(buf), fp);
    if (n == 0 || ferror(fp)) {
      break;
    }
    data->append(std::string(buf, n));
  }

  status = pclose(fp);
  return (status == 0);
}

int configure::get_int(const string& key)
{
	if(kv_.find(key) != kv_.end() ) {
		int ret = atoi(kv_[key].c_str());
		return ret;
	}
	return -1;
}
string configure::get_string(const string& key)
{
	if(kv_.find(key) != kv_.end() ) {
		return kv_[key];
	}
	return "";
}
int configure::check_key(const string& key)
{
	if(kv_.find(key) == kv_.end() ) {
		return -1;
	}
	return 0;
}
